﻿Public Class ItemArgHandler
    Implements IArgHandler

    Private Shared mItemTypes As Dictionary(Of String, TypeCode)
    Shared Sub New()
        mItemTypes = New Dictionary(Of String, TypeCode)
        mItemTypes.Add("BAR", Nothing)
        mItemTypes.Add("SMALLGEM", Nothing)
        mItemTypes.Add("BLOCKS", Nothing)
        mItemTypes.Add("ROUGH", Nothing)
        mItemTypes.Add("BOULDER/STONE", Nothing)
        mItemTypes.Add("WOOD", Nothing)
        mItemTypes.Add("DOOR", Nothing)
        mItemTypes.Add("FLOODGATE", Nothing)
        mItemTypes.Add("BED", Nothing)
        mItemTypes.Add("CHAIR", Nothing)
        mItemTypes.Add("CHAIN", Nothing)
        mItemTypes.Add("FLASK", Nothing)
        mItemTypes.Add("GOBLET", Nothing)
        mItemTypes.Add("INSTRUMENT", New TypeCode(ObjectType.ITEM, ObjectSubType.ITEM_INSTRUMENT))
        mItemTypes.Add("TOY", New TypeCode(ObjectType.ITEM, ObjectSubType.ITEM_TOY))
        mItemTypes.Add("WINDOW", Nothing)
        mItemTypes.Add("CAGE", Nothing)
        mItemTypes.Add("BARREL", Nothing)
        mItemTypes.Add("BUCKET", Nothing)
        mItemTypes.Add("ANIMALTRAP", Nothing)
        mItemTypes.Add("TABLE", Nothing)
        mItemTypes.Add("COFFIN", Nothing)
        mItemTypes.Add("STATUE", Nothing)
        mItemTypes.Add("CORPSE", Nothing)
        mItemTypes.Add("WEAPON", New TypeCode(ObjectType.ITEM, ObjectSubType.ITEM_WEAPON))
        mItemTypes.Add("ARMOR", New TypeCode(ObjectType.ITEM, ObjectSubType.ITEM_ARMOR))
        mItemTypes.Add("SHOES", New TypeCode(ObjectType.ITEM, ObjectSubType.ITEM_SHOES))
        mItemTypes.Add("SHIELD", New TypeCode(ObjectType.ITEM, ObjectSubType.ITEM_SHIELD))
        mItemTypes.Add("HELM", New TypeCode(ObjectType.ITEM, ObjectSubType.ITEM_HELM))
        mItemTypes.Add("GLOVES", New TypeCode(ObjectType.ITEM, ObjectSubType.ITEM_GLOVES))
        mItemTypes.Add("BOX", Nothing)
        mItemTypes.Add("BIN", Nothing)
        mItemTypes.Add("ARMORSTAND", Nothing)
        mItemTypes.Add("WEAPONRACK", Nothing)
        mItemTypes.Add("CABINET", Nothing)
        mItemTypes.Add("FIGURINE", Nothing)
        mItemTypes.Add("AMULET", Nothing)
        mItemTypes.Add("SCEPTER", Nothing)
        mItemTypes.Add("AMMO", New TypeCode(ObjectType.ITEM, ObjectSubType.ITEM_AMMO))
        mItemTypes.Add("CROWN", Nothing)
        mItemTypes.Add("RING", Nothing)
        mItemTypes.Add("EARRING", Nothing)
        mItemTypes.Add("BRACELET", Nothing)
        mItemTypes.Add("GEM", Nothing)
        mItemTypes.Add("ANVIL", Nothing)
        mItemTypes.Add("CORPSEPIECE", Nothing)
        mItemTypes.Add("REMAINS", Nothing)
        mItemTypes.Add("MEAT", Nothing)
        mItemTypes.Add("FISH", Nothing)
        mItemTypes.Add("FISH_RAW", Nothing)
        mItemTypes.Add("VERMIN", Nothing)
        mItemTypes.Add("PET", Nothing)
        mItemTypes.Add("SEEDS", Nothing)
        mItemTypes.Add("PLANT", Nothing)
        mItemTypes.Add("SKIN_TANNED", Nothing)
        mItemTypes.Add("LEAVES", Nothing)
        mItemTypes.Add("THREAD", Nothing)
        mItemTypes.Add("CLOTH", Nothing)
        mItemTypes.Add("TOTEM", Nothing)
        mItemTypes.Add("PANTS", New TypeCode(ObjectType.ITEM, ObjectSubType.ITEM_PANTS))
        mItemTypes.Add("BACKPACK", Nothing)
        mItemTypes.Add("QUIVER", Nothing)
        mItemTypes.Add("CATAPULTPARTS", Nothing)
        mItemTypes.Add("BALLISTAPARTS", Nothing)
        mItemTypes.Add("SIEGEAMMO", New TypeCode(ObjectType.ITEM, ObjectSubType.ITEM_SIEGEAMMO))
        mItemTypes.Add("BALLISTAARROWHEAD", Nothing)
        mItemTypes.Add("TRAPPARTS", Nothing)
        mItemTypes.Add("TRAPCOMP", New TypeCode(ObjectType.ITEM, ObjectSubType.ITEM_TRAPCOMP))
        mItemTypes.Add("DRINK", Nothing)
        mItemTypes.Add("POWDER_MISC", Nothing)
        mItemTypes.Add("CHEESE", Nothing)
        mItemTypes.Add("FOOD", New TypeCode(ObjectType.ITEM, ObjectSubType.ITEM_FOOD))
        mItemTypes.Add("LIQUID_MISC", Nothing)
        mItemTypes.Add("COIN", Nothing)
        mItemTypes.Add("GLOB", Nothing)
        mItemTypes.Add("ROCK", Nothing)
        mItemTypes.Add("PIPE_SECTION", Nothing)
        mItemTypes.Add("HATCH_COVER", Nothing)
        mItemTypes.Add("GRATE", Nothing)
        mItemTypes.Add("QUERN", Nothing)
        mItemTypes.Add("MILLSTONE", Nothing)
        mItemTypes.Add("SPLINT", Nothing)
        mItemTypes.Add("CRUTCH", Nothing)
        mItemTypes.Add("TRACTION_BENCH", Nothing)
        mItemTypes.Add("ORTHOPEDIC_CAST", Nothing)
        mItemTypes.Add("TOOL", New TypeCode(ObjectType.ITEM, ObjectSubType.ITEM_TOOL))
        mItemTypes.Add("SLAB", Nothing)
        mItemTypes.Add("EGG", Nothing)
        mItemTypes.Add("BOOK", Nothing)

        mItemTypes.Add("NONE", Nothing)

        mItemTypes.Add("ANY_CRAFT", Nothing)
        mItemTypes.Add("ANY_RAW_MATERIAL", Nothing)
        mItemTypes.Add("CRAFTS", Nothing)
        mItemTypes.Add("METAL_ORE", New TypeCode(ObjectType.INORGANIC, ObjectSubType.INORGANIC))
    End Sub

    Public Shared ReadOnly Property ItemInfo As IDictionary(Of String, TypeCode)
        Get
            Return mItemTypes
        End Get
    End Property

    Public ReadOnly Property DefaultTypeData As String Implements IArgHandler.DefaultTypeData
        Get
            Return ""
        End Get
    End Property

    Public ReadOnly Property DefaultValue(library As RawLibrary, obj As RawObject, argument As ArgumentDefinition) As String Implements IArgHandler.DefaultValue
        Get
            Return ""
        End Get
    End Property

    Public Function GetValues(obj As RawObject, argument As ArgumentDefinition) As System.Collections.Generic.IEnumerable(Of String) Implements IArgHandler.GetValues
        Return Nothing
    End Function

    Public Function Parse(argParts As System.Collections.Generic.IEnumerator(Of String), arg As ArgumentDefinition) As String Implements IArgHandler.Parse
        Dim parts As New List(Of String)
        Dim consume As Integer = 1 'The number of extra argument parts to consume (items always consume 2)

        parts.Add(argParts.Current)
        If argParts.MoveNext Then
            parts.Add(argParts.Current)
        End If

        Return String.Join(":"c, parts)
    End Function

    Public ReadOnly Property TypeDataFormat As String Implements IArgHandler.TypeDataFormat
        Get
            Return ""
        End Get
    End Property

    Public Function ValidateArgument(library As RawLibrary, obj As RawObject, argument As ArgumentDefinition, value As String) As String Implements IArgHandler.ValidateArgument
        Dim parts() As String = value.Split(":"c)
        If parts.Count <> 2 Then
            Return "Item arguments must have 2 parts."
        End If

        If Not mItemTypes.ContainsKey(parts(0)) Then
            Return "Item Type is not valid."
        End If

        Dim type As TypeCode = mItemTypes(parts(0))
        If type Is Nothing And parts(1) <> "NONE" Then
            Return "Sub Type must be 'NONE' for the specified Type."
        End If

        If type IsNot Nothing Then
            If Not library.GetObjectsByTypeCode(type).Select(Function(obj1 As RawObject) obj1.objectId).Contains(parts(1)) Then
                Return "Invalid Sub Type for the specified type."
            End If
        End If

        Return Nothing
    End Function

    Public Function ValidateTypeData(typeData As String) As Boolean Implements IArgHandler.ValidateTypeData
        Return True
    End Function

    Public Function GetNavList(library As RawLibrary, obj As RawObject, argument As ArgumentDefinition, value As String) As IEnumerable(Of NavPoint) Implements IArgHandler.GetNavList
        Dim ret As New List(Of NavPoint)
        Dim parts() As String = value.Split(":"c)
        If parts.Length = 2 Then
            If mItemTypes.ContainsKey(parts(0)) Then
                Dim typeCode As TypeCode = mItemTypes(parts(0))
                If typeCode IsNot Nothing Then
                    Dim nav As New NavPoint(parts(1), parts(1))
                    ret.Add(nav)
                End If
            End If
        End If
        Return ret
    End Function

    Private Class ItenInfo
        Public Property ItemArgType As String
        Public Property ObjectType As ObjectType
    End Class
End Class
